package com.it.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * @Author: CaoYouGen
 * @DateTime: 2023/11/13/12:35
 * @注释: TODO
 **/

@Component
@Slf4j
public class UtilJWT {
    @Value ("${jwt.secretKey}")
    private String jwtSecretKey;
    
    /*
     * 创建jwt
     *
     * @param userInfo: 用户信息
     * @param authList:  用户权限列表
     * @return String 返回jwt（Json Web Token）
     * @author: CaoYouGen
     * @DateTime: 2023/11/13 12:39
     */
    public String createToken (String userInfo, List<String> authList) {
        // 创建时间
        Date currentTime = new Date();
        // 过期时间，5分钟后过期
        Date expiretime = new Date(currentTime.getTime() + (1000 * 60 * 5));
        
        // jwt的header信息
        HashMap<String, Object> header = new HashMap<>();
        header.put("alg", "HS256");
        header.put("typ", "JWT");
        return JWT.create()
              .withHeader(header) // 设置头部信息
              .withIssuedAt(currentTime) // 设置签发日期（创建时间）
              .withExpiresAt(expiretime) // 设置过期时间
              .withIssuer("thomas") // 设置签发人
              .withClaim("userInfo", userInfo) // 私有声明 可以自己定义
              .withClaim("authList", authList) // 私有声明 可以自己定义
              .sign(Algorithm.HMAC256(jwtSecretKey)); // 签名 使用HS256算法签名，并使用密钥
        // HS256是一种对称算法，这意味着只有一个密钥，在双方之间共享。 使用相同的密钥生成签名并对其进行验证。 应特别注意钥匙是否保密。
    }
    
    /*
     * 验签jwt的签名简称验签
     * @DateTime: 2023/11/13 19:09
     *
     * @param token: 需要验签的token
     * @return boolean 验签结果
     * @author: Coke
     */
    public boolean verifyToken (String token) {
        // 创建一个验签类对象
        JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(jwtSecretKey)).build();
        try {
            // 验签，如果不报错，则说明 jwt 是合法的，而且也没有过期
            DecodedJWT verify = jwtVerifier.verify(token);
            return true;
        } catch (JWTVerificationException e) {
            // 如果报错说明 jwt 为非法的，或者已过期（已过期也属于非法的）
            e.printStackTrace();
            log.error("验证失败：{}", token);
        }
        return false;
    }
    
    /*
     * 获取用户信息
     * @DateTime: 2023/11/13 19:20
     *
     * @param token: jwt
     * @return String 用户信息
     * @author: Coke
     */
    public String getUserInfo (String token) {
        // 创建一个jwt验签对象
        JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(jwtSecretKey)).build();
        try {
            // 验签
            DecodedJWT verify = jwtVerifier.verify(token);
            String userInfo = verify.getClaim("userInfo").asString();
            return userInfo;
        } catch (JWTCreationException e) {
            e.printStackTrace();
        }
        return null;
    }
    
    /*
     * 获取用户的权限列表
     * @DateTime: 2023/11/13 19:25
     *
     * @param token: jwt
     * @return List<String> 权限列表
     * @author: Coke
     */
    public List<String> getUserAuth (String token) {
        // 创建一个jwt验签对象
        JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(jwtSecretKey)).build();
        try {
            DecodedJWT verify = jwtVerifier.verify(token);
            List<String> authList = verify.getClaim("authList").asList(String.class);
            return authList;
        }catch (JWTCreationException e){
            e.printStackTrace();
            return null;
        }
    }
}
